﻿namespace CloudNinja.Metering.TypeRegistration
{
    using System;
    using System.Configuration;
    using System.Text;

    using CloudNinja.Metering.Authentication;
    using CloudNinja.Metering.BlobLeaseUtil;
    using CloudNinja.Metering.Common;
    using CloudNinja.Metering.Common.Configuration;
    using CloudNinja.Metering.Common.Logging;
    using CloudNinja.Metering.Data;

    using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
    using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling;
    using Microsoft.Practices.EnterpriseLibrary.TransientFaultHandling.Configuration;
    using Microsoft.Practices.Unity;

    using MeteringRepositoryClient = CloudNinja.Metering.Common.MeteringRepositoryClient;

    public static class MeteringContainerBootstrapper
    {
        public static void RegisterTypes(IUnityContainer container)
        {
            var retryStrategy = new ExponentialBackoff(
                5,
                TimeSpan.FromSeconds(1),
                TimeSpan.FromMinutes(1),
                TimeSpan.FromSeconds(5));

            var storageRetryPolicy = new RetryPolicy<StorageTransientErrorDetectionStrategy>(retryStrategy);

            ContainerBootstrapper.RegisterTypes(container);

            var meteringSection = ConfigurationManager.GetSection("MeteringConfiguration") as MeteringSection;
            if (meteringSection == null)
            {
                throw new ApplicationException("CANNOT FIND THE METERING SECTION IN CONFIGURATION.");
            }

            container.RegisterType<IApiKeyStore, ClientApiKeyStore>(
                new ContainerControlledLifetimeManager(),
                new InjectionConstructor(meteringSection.MeteringRepositorySettings.APIKey));

            container.RegisterType<IHmacHelper, HmacHelper>(new ContainerControlledLifetimeManager());

            var repositoryInjectionCtor = new InjectionConstructor(
                meteringSection.MeteringRepositorySettings.UserId,
                meteringSection.MeteringRepositorySettings.MeteringDataServiceEndpoint);

            container.RegisterType<IMeteringRepository, MeteringRepositoryClient>(
                new ContainerControlledLifetimeManager(), repositoryInjectionCtor);

            container.RegisterType<ILicenseToRun, LicenseToRun>(new ContainerControlledLifetimeManager(), new InjectionConstructor(storageRetryPolicy));

            var tickTockInjoctionCtor = new InjectionConstructor(container.Resolve<ILicenseToRun>(), container.Resolve<ILogger>());

            container.RegisterType<ITickTock, TickTock>(new ContainerControlledLifetimeManager(), tickTockInjoctionCtor);

            container.RegisterInstance(typeof(Metering), new ContainerControlledLifetimeManager());
        }
    }
}